#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "../skill.h"
#include "../database.h"
#include "../engines/adeptengine.h"
#include "../engines/namegiverengine.h"
#include "aboutdialog.h"
#include "../misc/charactercountercreator.h"

QList<QListWidgetItem*> items(QListWidget* list)
{
  QList<QListWidgetItem*> result;
  for(int i=0;i<list->count();++i)
    result << list->item(i);
  return result;
}

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow), _character(nullptr)
{
  ui->setupUi(this);
  ui->progressBar->hide();
  ui->sa_character->hide();

  foreach(const Discipline& d, Database::disciplines()) ui->cb_Discipline->addItem(d.name());

  foreach(const Skill& s, Database::skills()) ui->lst_availableSkills->addItem(s.name());
  refreshPrimeAttributes();
}

MainWindow::~MainWindow()
{
  delete ui;
}

void MainWindow::rollCharacter()
{
  QVariantMap args;
  args[NameGiverEngine::ARG_RACE] = (int)ed::Race::fromString(ui->cb_race->currentText());
  args[NameGiverEngine::ARG_CREATION_POINTS] = ui->sp_creationPoints->value();
  args[NameGiverEngine::ARG_LEGEND_POINTS] = ui->sp_legendPoints->value();
  args[NameGiverEngine::ARG_RAISE_KNOWN_SKILL_PROBABILITY] = ui->sld_raiseKnownSkills->value() * 1./100.;
  args[NameGiverEngine::ARG_LEARN_NEW_SKILL_PROBABILITY] = ui->sld_learnNewSkills->value() * 1./100.;
  args[NameGiverEngine::ARG_RAISE_PRIME_SKILL_PROBABILITY] = ui->sld_raisePrimeSkills->value() * 1./100.;
  QVariantList primeAttributes;
  foreach(QListWidgetItem* item, items(ui->lst_primeAttributes))
  {
    if (item->checkState() == Qt::Checked) primeAttributes << (int)ed::Attribute::fromString(item->text());
  }
  args[NameGiverEngine::ARG_PRIME_ATTRIBUTES] = primeAttributes;
  QStringList primeSkills;
  foreach(QListWidgetItem* item, items(ui->lst_primeSkills)) primeSkills << item->text();
  args[NameGiverEngine::ARG_PRIME_SKILLS] = primeSkills;
  args[AdeptEngine::ARG_DISCIPLINE] = ui->cb_Discipline->currentText();
  args[AdeptEngine::ARG_RAISE_KNOWN_TALENT_PROBABLITY] = ui->sld_raiseKnownTalents->value() * 1./100.;
  args[AdeptEngine::ARG_LEARN_NEW_TALENT_PROBABLITY] = ui->sld_learnNewTalent->value() * 1./100.;

  ui->progressBar->show();
  ui->f_toolBar->setEnabled(false);
  ui->sa_settings->setEnabled(false);
  if (ui->grp_adept->isChecked()) rollAdept(args);
  else rollNameGiver(args);
  ui->sa_settings->setEnabled(true);
  ui->f_toolBar->setEnabled(true);
  ui->progressBar->hide();
  ui->sa_character->show();
}

void MainWindow::addSkill()
{
  if (ui->lst_availableSkills->selectedItems().isEmpty()) return;
  QListWidgetItem* i = ui->lst_availableSkills->selectedItems().first();
  ui->lst_primeSkills->addItem(i->text());
  delete i;
  ui->lst_primeSkills->sortItems();
}

void MainWindow::delSkill()
{
  if (ui->lst_primeSkills->selectedItems().isEmpty()) return;
  QListWidgetItem* i = ui->lst_primeSkills->selectedItems().first();
  ui->lst_availableSkills->addItem(i->text());
  delete i;
  ui->lst_availableSkills->sortItems();
  setSkillFilter(ui->lne_filterSkills->text());
}

void MainWindow::setSkillFilter(const QString& filter)
{
  foreach(QListWidgetItem* item, items(ui->lst_availableSkills)) item->setHidden(!item->text().contains(filter,Qt::CaseInsensitive));
}

void MainWindow::rollNameGiver(const QVariantMap &args)
{
  delete _character;
  NameGiverEngine eg;
  _character = eg.create(args);
  _character->set_name(ui->le_name->text());
  ui->characterWidget->setCharacter(_character);
  ui->l_log->setText(eg.log());
}

void MainWindow::rollAdept(const QVariantMap &args)
{
  delete _character;
  AdeptEngine eg;
  _character = eg.create(args);
  _character->set_name(ui->le_name->text());
  ui->characterWidget->setCharacter(_character);
  ui->l_log->setText(eg.log());
}

void MainWindow::refreshPrimeAttributes()
{
  Discipline d = Database::discipline(ui->cb_Discipline->currentText());

  int oldIndex = ui->cb_race->currentIndex();
  ui->cb_race->clear();
  foreach(ed::Race r, ed::Race::values())
  {
    if (!d.racialRestrictions().contains(r) || !ui->grp_adept->isChecked()) ui->cb_race->addItem((QString)r);
  }
  ui->cb_race->setCurrentIndex(oldIndex);

  foreach(QListWidgetItem* item, items(ui->lst_primeAttributes))
  {
    ed::Attribute a = ed::Attribute::fromString(item->text());
    item->setCheckState(d.baseAttributes().contains(a) && ui->grp_adept->isChecked() ? Qt::Checked : Qt::Unchecked);
  }
}

#include <QFileDialog>

void MainWindow::toCSV()
{
  if (_character == nullptr) return;
  QFile outFile(QFileDialog::getSaveFileName(0,QString(),QString(),"*.csv"));
  outFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
  outFile.write(ui->characterWidget->csv().toUtf8());
  outFile.close();
}

void MainWindow::toIdd()
{
  if (_character == nullptr) return;
  QFile outFile(QFileDialog::getSaveFileName(0,QString(),QString(),"*.xml"));
  outFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
  outFile.write(ui->characterWidget->idd().toUtf8());
  outFile.close();
}

void MainWindow::toPDF()
{
  CharacterCounterCreator ccc(dynamic_cast<NameGiver*>(_character));
  if (ccc.exec() == QDialog::Accepted)
  {
    ccc.save(QFileDialog::getSaveFileName(0,QString(),QString(),"*.png"));
  }
}

void MainWindow::about()
{
  AboutDialog dlg;
  dlg.exec();
}

void MainWindow::rollName()
{
  QString r = "human";
  if (_character != nullptr)
  {
    switch(static_cast<NameGiver*>(_character)->race())
    {
    case ed::Race_Elfe:
      r = "elf";
      break;
    case ed::Race_Humain:
      r = "human";
      break;
    case ed::Race_Nain:
      r = "dwarf";
      break;
    case ed::Race_Obsidien:
      r = "arabic";
      break;
    case ed::Race_Ork:
      r = "orc";
      break;
    case ed::Race_Sylphelin:
      r = "hobbit";
      break;
    case ed::Race_Troll:
      r = "barbarian";
      break;
    case ed::Race_Tskrang:
      r = "reptilian";
      break;
    }
  }

  ui->le_name->setText(Database::randomName(r));
  ui->l_surname->setText(Database::randomName("surnames"));
}
